package cn.lijian.goods.user.web.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.itcast.commons.CommonUtils;
import cn.itcast.servlet.BaseServlet;
import cn.lijian.goods.user.domain.User;
import cn.lijian.goods.user.service.UserService;
import cn.lijian.goods.user.service.exception.UserException;

/**
 * �û�ģ�� ���Ʋ�
 * 
 * @author lijian
 * 
 */
public class UserServlet extends BaseServlet {

	private UserService userService = new UserService();

	/**
	 * 退出功能
	 * 
	 * @param req
	 * @param resp
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String quit(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		req.getSession().invalidate();// 销毁session
		return "r:/jsps/user/login.jsp";
	}

	/**
	 * 
	 * @param req
	 * @param resp
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String updatePassword(HttpServletRequest req,
			HttpServletResponse resp) throws ServletException, IOException {
		User formUser = CommonUtils.toBean(req.getParameterMap(), User.class);
		User user = (User) req.getSession().getAttribute("sessionUser");
		// 如果用户没有登录，返回到登录页面
		if (user == null) {
			req.setAttribute("msg", "您还没有登录");
			return "f:/jsps/user/login.jsp";
		}
		try {
			userService.updatePassword(user.getUid(),
					formUser.getNewloginpass(), formUser.getLoginpass());
			req.setAttribute("msg", "修改密码成功");
			req.setAttribute("code", "success");
			return "f:/jsps/msg.jsp";
		} catch (UserException e) {
			req.setAttribute("msg", e.getMessage());
			req.setAttribute("user", formUser);
			return "f:/jsp/user/pwd.jsp";
		}
	}

	/**
	 * 用户名是否注册校验
	 * 
	 * @param req
	 * @param resp
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String ajaxValidateLoginname(HttpServletRequest req,
			HttpServletResponse resp) throws ServletException, IOException {
		String loginname = req.getParameter("loginname");
		boolean b = userService.ajaxValidateLoginname(loginname);
		resp.getWriter().print(b);
		return null;
	}

	/**
	 * Email 是否注册校验
	 * 
	 * @param req
	 * @param resp
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String ajaxValidateEmail(HttpServletRequest req,
			HttpServletResponse resp) throws ServletException, IOException {
		String email = req.getParameter("email");
		boolean b = userService.ajaxValidateEmail(email);
		resp.getWriter().print(b);
		return null;

	}

	/**
	 * 验证码校验
	 * 
	 * @param req
	 * @param resp
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String ajaxValidateVerifyCode(HttpServletRequest req,
			HttpServletResponse resp) throws ServletException, IOException {
		/**
		 * 获取输入框的验证码
		 */
		String verifyCode = req.getParameter("verifyCode");
		/**
		 * 获取图片的真实验证码
		 */
		String vcode = (String) req.getSession().getAttribute("vCode");
		/**
		 * 忽略大小写比较
		 */
		boolean b = verifyCode.equalsIgnoreCase(vcode);
		resp.getWriter().print(b);
		return null;
	}

	/**
	 * 注册功能
	 * 
	 * @param req
	 * @param resp
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String regist(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		// 封装表单数据到 user
		User formUser = CommonUtils.toBean(req.getParameterMap(), User.class);
		// 校验,如果校验失败，保存错误信息，返回到 register.jsp 显示
		Map<String, String> errors = validateRegist(formUser, req.getSession());
		if (errors.size() > 0) {
			req.setAttribute("form", formUser);
			req.setAttribute("errors", errors);
			return "f:/jsps/user/regist.jsp";
		}
		// 使用 service 完成业务
		userService.regist(formUser);
		// 保存成功信息，转发到 msg.jsp
		req.setAttribute("code", "success");
		req.setAttribute("msg", "注册成功，请到邮箱激活");
		return "f:/jsps/msg.jsp";
	}

	/**
	 * 注册校验 对表单的字段进行逐个校验，如果有错误使用当前字段名称为key,错误信息为 value ，保存到 map 中
	 * 
	 * @param user
	 * @return
	 * @author lijian
	 */
	private Map<String, String> validateRegist(User user, HttpSession session) {
		Map<String, String> errors = new HashMap<String, String>();
		// 用户名校验
		String loginname = user.getLoginname();
		if (loginname == null || loginname.trim().isEmpty()) {
			errors.put("loginname", "用户名不能为空");
		} else {
			if (loginname.length() < 3 || loginname.length() > 20) {
				errors.put("loginname", "用户名长度必须在 3 - 20 之间");
			} else {
				if (!userService.ajaxValidateLoginname(loginname)) {
					errors.put("loginname", "用户名已注册");
				}
			}

		}
		// 密码校验
		String loginpass = user.getLoginpass();
		if (loginpass == null || loginpass.trim().isEmpty()) {
			errors.put("loginpass", "密码不能为空");
		} else {
			if (loginpass.length() < 3 || loginpass.length() > 20) {
				errors.put("loginpass", "密码长度必须在 3 - 20 之间");
			}
		}
		// 确认密码校验
		String reloginpass = user.getReloginpass();
		if (reloginpass == null || reloginpass.trim().isEmpty()) {
			errors.put("reloginpass", "确认密码不能为空");
		} else {
			if (!reloginpass.equals(loginpass)) {
				errors.put("reloginpass", "两次密码输入不一致");
			}
		}
		// Email 校验
		String email = user.getEmail();
		if (email == null || email.trim().isEmpty()) {
			errors.put("email", "邮箱不能为空");
		} else {
			if (!email
					.matches("^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\\.[a-zA-Z0-9_-]{2,3}){1,2})$")) {
				errors.put("email", "Email 格式错误");
			} else {
				if (!userService.ajaxValidateEmail(email)) {
					errors.put("email", "该 Email 已被注册");
				}
			}
		}

		// 验证码校验
//		String verifyCode = user.getVerifyCode();
//		String vcode = (String) session.getAttribute("vCode");
//		if (verifyCode == null || verifyCode.trim().isEmpty()) {
//			errors.put("verifyCode", "验证码不能为空");
//		} else {
//			if (!verifyCode.equalsIgnoreCase(vcode)) {
//				errors.put("verifyCode", "验证码错误");
//			}
//		}
		return errors;
	}

	/**
	 * 激活功能
	 * 
	 * @param req
	 * @param resp
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String activation(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		// 获取激活码
		String code = req.getParameter("activationCode");
		try {
			userService.activation(code);
			req.setAttribute("code", "success");
			req.setAttribute("msg", "恭喜，激活成功，请马上登录");
		} catch (UserException e) {
			// TODO Auto-generated catch block
			req.setAttribute("msg", e.getMessage());
			req.setAttribute("code", "error");// 通知 msg.jsp 显示 叉号
		}
		// 调用 service 方法，看是否有异常，如果有异常，取出异常信息，保存到 request 中，转发 到 msg.jsp
		// 如果没有异常，保存成功信息，转发到 msg.jsp
		return "f:/jsps/msg.jsp";
	}

	/**
	 * 登录功能
	 * 
	 * @param req
	 * @param resp
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String login(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// 封装表单参数到 user
		User formUser = CommonUtils.toBean(req.getParameterMap(), User.class);
		// 校验表单数据

		Map<String, String> errors = validateLogin(formUser, req.getSession());
		
		if (errors.size() > 0) {
			req.setAttribute("form", formUser);
			req.setAttribute("errors", errors);
			req.setAttribute("msg", "验证码错误");
			return "f:/jsps/user/login.jsp";
		}
		
		// 使用 service 完成业务
		// 使用 service 查询，得到 user
		User user = userService.login(formUser);
		// 查看 用户是否存在
		if (user == null) {
			req.setAttribute("msg", "用户名或密码错误");
			req.setAttribute("user", formUser);
			return "f:/jsps/user/login.jsp";
		} else {
			if (!user.isStatus()) {// 未激活
				req.setAttribute("msg", "您还没有激活该账号");
				req.setAttribute("user", formUser);
				return "f:/jsps/user/login.jsp";
			} else {
				// 登录成功，保存用户到 session
				req.getSession().setAttribute("sessionUser", user);
				// 保存用户名到 cookie ，下次可以提示，因为用户名可能有中文，处理中文
				String loginname = user.getLoginname();
				loginname = URLEncoder.encode(loginname, "utf-8");
				Cookie cookie = new Cookie("loginname", loginname);
				cookie.setMaxAge(60 * 60 * 24 * 10);// 10 天
				resp.addCookie(cookie);
				return "r:/index.jsp";// 重定向到主页
			}
		}
		// 如果不存在，保存错误信息，用户名或密码错误
		// 保存表单数据，为了回显
		// 转发到 login.jsp
		// 如果存在，查看状态，
		// 如果状态为 false ，保存错误信息，没有激活
		// 保存表单数据，为了回显
		// 转发到 login.jsp
		// 登录成功，保存user 到 session
		// 保存用户名到 cookie
	}

	/**
	 * 登录校验方法
	 * 
	 * @param user
	 * @param session
	 * @return
	 * @author lijian
	 */
	private Map<String, String> validateLogin(User user, HttpSession session) {
		Map<String, String> errors = new HashMap<String, String>();

		// 用户名校验
		String loginname = user.getLoginname();
		if (loginname == null || loginname.trim().isEmpty()) {
			errors.put("loginname", "用户名不能为空");
		} else {
			if (loginname.length() < 3 || loginname.length() > 20) {
				errors.put("loginname", "用户名长度必须在 3 - 20 之间");
			} 
		}
		// 密码校验
		String loginpass = user.getLoginpass();
		if (loginpass == null || loginpass.trim().isEmpty()) {
			errors.put("loginpass", "密码不能为空");
		} else {
			if (loginpass.length() < 3 || loginpass.length() > 20) {
				errors.put("loginpass", "密码长度必须在 3 - 20 之间");
			}
		}
		// 验证码校验
//		String verifyCode = user.getVerifyCode();
//		String vcode = (String) session.getAttribute("vCode");
//		if (verifyCode == null || verifyCode.trim().isEmpty()) {
//			errors.put("verifyCode", "验证码不能为空");
//		} else {
//			if (!verifyCode.equalsIgnoreCase(vcode)) {
//				errors.put("verifyCode", "验证码错误");
//			}
//		}

		return errors;

	}
}
